package com.onec.service.im.cocurrent;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.onec.service.im.util.ThreadUtil;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import org.checkerframework.checker.nullness.qual.Nullable;

public class CallbackTaskScheduler {

  static ListeningExecutorService executorService = null;

  static {
    ExecutorService pool = ThreadUtil.getMixedTargetThreadPool();
    executorService = MoreExecutors.listeningDecorator(pool);
  }

  public static <R> void add(CallBackTask<R> task) {

    ListenableFuture<R> future = executorService.submit(new Callable<R>() {
      @Override
      public R call() throws Exception {
        R r = task.execute();
        return r;
      }
    });

    Futures.addCallback(future, new FutureCallback<R>() {
      @Override
      public void onSuccess(@Nullable R r) {
        task.runBack(r);
      }

      @Override
      public void onFailure(Throwable throwable) {
        task.onException(throwable);
      }
    }, executorService);
  }
}
